package com.xiaolei.fastnio.http

import com.xiaolei.fastnio.http.Comm.HttpSessionStore
import com.xiaolei.fastnio.http.Comm.RequestBodyFile
import com.xiaolei.fastnio.library.Client.Session
import com.xiaolei.fastnio.library.Protocol.Cleanable
import java.util.*
import kotlin.collections.HashMap

/**
 * 把用户的请求，封装成Request对象
 */
class Request : HashMap<String, String>(), Cleanable
{
    var session: Session? = null
        set(value)
        {
            body.session = session
            field = value
        }

    var response: Response? = null

    val body = RequestBodyFile()

    /**
     * 解析Cookie
     */
    val cookies = HashMap<String, String>()
        get()
        {
            if (field.isEmpty())
            {
                val cks = this["Cookie"] ?: ""
                val ckList = cks.split(";").filter { it.contains("=") }
                for (cookie in ckList)
                {
                    val key_value = cookie.split("=")
                    val key = key_value[0]
                    val value = key_value[1]
                    field[key] = value
                }
            }
            return field
        }

    // 会话ID
    val sessionId: String
        get() = cookies["NioSessionId"] ?: UUID.randomUUID().toString()

    /**
     * 网络请求的Session
     */
    val httpSession: HttpSession
        get()
        {
            // 如果cookie不存在，则新添加进去
            if (response?.cookies?.contains("NioSessionId") != true)
            {
                response?.addCookie("NioSessionId", sessionId)
            }
            return HttpSessionStore.getOrCreateSession(sessionId)
        }

    // 接受的数据类型
    val accept
        get() = this["Accept"] ?: ""

    // 客户端身份验证代理验证
    val userAgent
        get() = this["User-Agent"] ?: ""

    // 客户端连接模式
    val connection
        get() = this["Connection"] ?: ""

    // 客户端主机
    val host
        get() = this["Host"] ?: ""

    // 客户端可以接受的语言
    val acceptLanguage
        get() = this["Accept-Language"] ?: ""

    // 客户端可以接受的编码
    val acceptEncoding
        get() = this["Accept-Encoding"] ?: ""

    // 内容长度
    val contentLength
        get() = this["Content-Length"]?.toInt() ?: -1

    // 内容类型
    val contentType
        get() = this["Content-Type"] ?: ""

    // 请求方式
    var method: String = ""
        set(value)
        {
            field = value.toUpperCase()
        }

    // 请求Uri
    var uri: String = ""
        set(url)
        {
            field = url
            val urlAndParamsStr = url.split("?")
            if (urlAndParamsStr.isNotEmpty())
            {
                field = urlAndParamsStr[0]
            }
            if (urlAndParamsStr.size >= 2)
            {
                val params = urlAndParamsStr[1]
                val keyValues = params.split("&")
                for (keyValue in keyValues)
                {
                    val keyAndValue = keyValue.split("=")
                    if (keyAndValue.size == 2)
                    {
                        val key = keyAndValue[0]
                        val value = keyAndValue[1]
                        val values = queryParams[key] ?: LinkedList()
                        if (!queryParams.containsKey(key))
                        {
                            queryParams[key] = values
                        }
                        values.add(value)
                    }
                }
            }
        }

    // 请求携带参数
    val queryParams = LinkedHashMap<String, LinkedList<String>>()
    
    // 请求协议
    var scheme: String = ""

    override fun onClear()
    {
        method = ""
        uri = ""
        scheme = ""
        queryParams.clear()
        body.onClear()
        this.clear()
        cookies.clear()
        response = null
        session = null
    }

    override fun toString(): String
    {
        return "[Request]:[method:$method,uri:$uri,scheme:$scheme]]"
    }
}
